package com.yuju.roomStatus.service.impl;

import com.yuju.enums.CheckinTypeEnum;
import com.yuju.hotel.model.PriceDetailModel;
import com.yuju.hotel.model.PriceSchemeModel;
import com.yuju.hotel.model.RoomTypeModel;
import com.yuju.hotel.service.IPriceDetailService;
import com.yuju.hotel.service.IPriceSchemeService;
import com.yuju.hotel.service.IRoomTypeService;
import com.yuju.roomStatus.dao.IRoomTypeStatusDao;
import com.yuju.roomStatus.model.RoomStatusModel;
import com.yuju.roomStatus.model.RoomTypeStatusModel;
import com.yuju.roomStatus.service.IRoomStatusService;
import com.yuju.roomStatus.service.IRoomTypeStatusService;
import com.yuju.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 
 * 类名：RoomTypeStatusServiceImpl  <br />
 *
 * 功能：房型状态
 *
 * @author : jiangp <br />
 * @Date : 2017年12月13日 下午6:16:02  <br />
 * @version : 1.1 <br />
 */
@Service
public class RoomTypeStatusServiceImpl implements IRoomTypeStatusService {
    @Autowired
    private IRoomTypeService roomTypeService;

    @Autowired
    private IPriceDetailService priceDetailService;

    @Autowired
    private IPriceSchemeService priceSchemeService;

    @Autowired
    private IRoomStatusService roomStatusService;

    @Autowired
    private IRoomTypeStatusDao roomTypeStatusDao;

    //月租金计算时固定月天数
    private static Integer FIX_MONTH_DAY_COUNT = 30;

    //除法时保留小数点后两位
    private static Integer RETAIL_DECIMAL_COUNT = 2;
    
    /**
     * 
     * 功能：计算公寓房总租金<br/>
     *
     * @author jiangp
     * @Date 2017年12月13日 下午6:16:19 <br/>
     */
    private BigDecimal getTotalPrice(Date startday, Date endday, BigDecimal monthPrice) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Integer month = DateUtil.getActDiffMonth(sdf.format(startday), sdf.format(endday));
        Integer day = DateUtil.getIngoreMonthDiffDay(sdf.format(startday), sdf.format(endday));
        BigDecimal total = BigDecimal.ZERO;
        total = total.add(monthPrice.multiply(BigDecimal.valueOf(month)));
        BigDecimal beyonPrice = monthPrice.divide(BigDecimal.valueOf(FIX_MONTH_DAY_COUNT),
                RETAIL_DECIMAL_COUNT, BigDecimal.ROUND_DOWN);
        beyonPrice = beyonPrice.multiply(BigDecimal.valueOf(day));
        total = total.add(beyonPrice);

        return total;

    }

    private BigDecimal getAveragePirce(Date startday, Date endday, BigDecimal totalPrice) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        BigDecimal averagePrice = BigDecimal.ZERO;
        averagePrice = totalPrice.divide(BigDecimal.valueOf(DateUtil.getDiffDay(sdf.format(endday),sdf.format(startday))!=0?DateUtil.getDiffDay(sdf.format(endday),sdf.format(startday)):1),
                RETAIL_DECIMAL_COUNT, BigDecimal.ROUND_DOWN);
        return averagePrice;
    }

    /**
     *
     * 功能：根据月租金和入住离店时间计算公寓房日均价<br/>
     *
     * @author jiangp
     * @Date 2017年12月13日 下午6:16:37 <br/>
     */
    private BigDecimal getDayPirce(Date startday, Date endday, BigDecimal monthPrice) {
        BigDecimal totalPrice = getTotalPrice(startday,endday,monthPrice);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        BigDecimal averagePrice = BigDecimal.ZERO;
        averagePrice = totalPrice.divide(BigDecimal.valueOf(DateUtil.getDiffDay(sdf.format(endday),sdf.format(startday))),
                RETAIL_DECIMAL_COUNT, BigDecimal.ROUND_DOWN);
        return averagePrice;
    }

    /**
     * 
     * 功能: 获得房型价格<br/>
     * 
     * 重写：jiangp <br/>
     * 
     * @Date ：2017年12月13日 下午6:16:54<br/>
     * 
     * @param roomTypeReserveModel
     * @return <br/>
     * @see com.yuju.roomStatus.service.IRoomTypeStatusService#getRoomTypePrice(com.yuju.roomStatus.model.RoomTypeStatusModel)
     */
    @Override
    public List<RoomTypeStatusModel> getRoomTypePrice(RoomTypeStatusModel roomTypeReserveModel){
        List<RoomTypeStatusModel> result = new ArrayList<>();
        Byte checkinType = roomTypeReserveModel.getCheckinType();
        String checkinStandard = roomTypeReserveModel.getCheckinStandardId();
        String priceScheme = roomTypeReserveModel.getPriceSchemeId();
        String hotelId = roomTypeReserveModel.getHotelId();

        if (hotelId == null || CheckinTypeEnum.CHECKIN_NONE.getValue().equals(checkinType)) {
            return result;
        }

        if ((checkinType.equals(CheckinTypeEnum.CHECKIN_QT.getValue()) && priceScheme == null)
                || (!checkinType.equals(CheckinTypeEnum.CHECKIN_QT.getValue()) && checkinStandard == null)) {
            return result;
        }

        //自用房和免费房的价格和早餐数都为0
        if (checkinType.equals(CheckinTypeEnum.CHECKIN_MF.getValue())
                || checkinType.equals(CheckinTypeEnum.CHECKIN_ZY.getValue())) {
            RoomTypeModel roomTypeModel = new RoomTypeModel();
            roomTypeModel.setHotelId(hotelId);
            List<RoomTypeModel> roomTypeModelList = roomTypeService.list(roomTypeModel);
            for (RoomTypeModel item: roomTypeModelList) {
                RoomTypeStatusModel roomTypePrice = new RoomTypeStatusModel();
                roomTypePrice.setHotelId(hotelId);
                roomTypePrice.setRoomTypeId(item.getRoomTypeId());
                result.add(roomTypePrice);
            }
        }
        //全天房
        else if (checkinType.equals(CheckinTypeEnum.CHECKIN_QT.getValue())) {
            return roomTypeStatusDao.getPirceBySchemeId(roomTypeReserveModel);
        }
        else {
            PriceDetailModel priceDetailModel = new PriceDetailModel();
            priceDetailModel.setHotelId(hotelId);
            priceDetailModel.setCheckinStandardId(roomTypeReserveModel.getCheckinStandardId());
            List<PriceDetailModel> priceDetailModelList = priceDetailService.list(priceDetailModel);
            for (PriceDetailModel item: priceDetailModelList) {
                RoomTypeStatusModel roomTypePrice = new RoomTypeStatusModel();
                roomTypePrice.setHotelId(hotelId);
                roomTypePrice.setRoomTypeId(item.getRoomTypeId());
                //公寓房单独处理
                if (checkinType.equals(CheckinTypeEnum.CHECKIN_GY.getValue())) {
                    //如果入住标准中没有价格，则直接使用门市月租金
                    if (item.getPrice() == null && item.getRoomTypeMonthlyPrice() != null) {
                        roomTypePrice.setLowestMonthPrice(item.getRoomTypeMonthlyPrice());
                    }
                    else
                    {
                        roomTypePrice.setLowestMonthPrice(item.getPrice());
                    }

                    //房价默认为房型的月门市价
                    roomTypePrice.setMonthPrice(item.getRoomTypeMonthlyPrice());

                    BigDecimal monthPrice = roomTypePrice.getMonthPrice();

                    roomTypePrice.setTotalPrice(getTotalPrice(roomTypeReserveModel.getCheckinTime(),
                            roomTypeReserveModel.getCheckoutTime(), monthPrice));
                    roomTypePrice.setDayPrice(getAveragePirce(roomTypeReserveModel.getCheckinTime(),
                            roomTypeReserveModel.getCheckoutTime(), roomTypePrice.getTotalPrice()));
                }
                else
                {
                    roomTypePrice.setRoomPrice(item.getPrice());
                }

                result.add(roomTypePrice);
            }
        }

        return result;
    }

    /**
     * 
     * 功能: 获得房型可预订数、价格、早餐数<br/>
     * 
     * 重写：jiangp <br/>
     * 
     * @Date ：2017年12月13日 下午6:17:18<br/>
     * 
     * @param roomTypeReserveModel
     * @return <br/>
     * @see com.yuju.roomStatus.service.IRoomTypeStatusService#getReserveNum(com.yuju.roomStatus.model.RoomTypeStatusModel)
     */
    @Override
    public List<RoomTypeStatusModel> getReserveNum(RoomTypeStatusModel roomTypeReserveModel) {
        //获得房型的可预订数
        List<RoomTypeStatusModel> result = this.getReserveCount(roomTypeReserveModel);

        //更新房型价格
        List<RoomTypeStatusModel> priceList = getRoomTypePrice(roomTypeReserveModel);

        for (RoomTypeStatusModel roomType: result) {
            String roomTypeId = roomType.getRoomTypeId();
            //更新价格和早餐
            for (RoomTypeStatusModel item : priceList ) {
                if (roomTypeId.equals(item.getRoomTypeId())) {
                    roomType.setRoomPrice(item.getRoomPrice());
                    roomType.setDayPrice(item.getDayPrice());
                    roomType.setMonthPrice(item.getMonthPrice());
                    roomType.setLowestMonthPrice(item.getLowestMonthPrice());
                    roomType.setBreakCount(item.getBreakCount());
                    roomType.setTotalPrice(item.getTotalPrice());
                    break;
                }
            }
        }

        return result;
    }

    /**
     * 
     * 功能：根据价格方案获得价格和早餐数<br/>
     *
     * @author jiangp
     * @Date 2017年12月15日 下午3:16:58 <br/>
     */
    @Override
    public List<RoomTypeStatusModel> getPirceBySchemeId(RoomTypeStatusModel roomTypeStatusModel){
        return roomTypeStatusDao.getPirceBySchemeId(roomTypeStatusModel);
    }

	/**
	 * 
	 * 功能：获得可预订房间数量：可预订房间数=非占用房间+可超订-预订房间数<br/>
	 *
	 * @author jiangp
	 * @Date 2017年12月16日 上午9:43:52 <br/>
	 */
    @Override
    public List<RoomTypeStatusModel> getReserveCount(RoomTypeStatusModel roomTypeStatusModel){
        return roomTypeStatusDao.getReserveCount(roomTypeStatusModel);
    }

	/**
	 * 
	 * 功能：根据房型验证房间数是否够预订，是否可入住。
	 * 输入参数必须包含roomTypeId和reserveVerifyCount。
	 * 输出参数包含验证每个房型的reserveVerifyStatus。<br/>
	 *
	 * @author jiangp
	 * @Date 2017年12月16日 上午9:45:03 <br/>
	 */
    @Override
    public List<RoomTypeStatusModel> verifyReserveRoomType(List<RoomTypeStatusModel> roomTypeStatusModelList,
                                                           String hotelId, Date checkinTime, Date checkoutTime){
        RoomTypeStatusModel roomTypeStatusModel = new RoomTypeStatusModel();
        roomTypeStatusModel.setHotelId(hotelId);
        roomTypeStatusModel.setCheckinTime(checkinTime);
        roomTypeStatusModel.setCheckoutTime(checkoutTime);

        List<RoomTypeStatusModel> list = this.getReserveCount(roomTypeStatusModel);

        for (RoomTypeStatusModel item: roomTypeStatusModelList) {
            for (RoomTypeStatusModel roomTypeReserveCount: list) {
                if (item.getRoomTypeId() != null && item.getRoomTypeId().equals(roomTypeReserveCount.getRoomTypeId())) {
                    if (item.getReserveVerifyCount() > roomTypeReserveCount.getReserveCount()) {
                        item.setReserveVerifyStatus(false);
                    }
                    break;
                }
            }
        }

        return roomTypeStatusModelList;
    }

	/**
	 * 
	 * 功能：根据开始和结束日期，月租金获得公寓房的总价、日均价<br/>
	 *
	 * @author jiangp
	 * @Date 2017年12月23日 上午9:52:45 <br/>
	 */
    @Override
    public RoomTypeStatusModel getApartPrice(Date startday, Date endday, BigDecimal monthPrice){
        RoomTypeStatusModel result = new RoomTypeStatusModel();
        result.setTotalPrice(getTotalPrice(startday, endday, monthPrice));
        result.setDayPrice(getAveragePirce(startday,endday,result.getTotalPrice()));
        result.setMonthPrice(monthPrice);
        return result;
    }


}
